Skip to content

Fix hooks: PowerShell quoting, stopTeammate helper, output docs#177

Merged
maystudios merged 1 commit intomainfrom
worktree-agent-aa990540
Mar 25, 2026
Merged

Fix hooks: PowerShell quoting, stopTeammate helper, output docs#177
maystudios merged 1 commit intomainfrom
worktree-agent-aa990540

Conversation

@maystudios
Copy link
Copy Markdown
Owner

Summary

  • shared.ts: Fix PowerShell WAV path quoting to use double-quote escaping instead of single-quote escaping, preventing breakage with paths containing PowerShell special characters
  • shared.ts: Add stopTeammate() exported helper function for permanent teammate termination via JSON stdout protocol
  • maxsim-teammate-idle.ts / maxsim-task-completed.ts: Add JSDoc output format documentation describing exit code semantics (0 = allow, 2 = block, JSON stdout = stop)

Test plan

  • npm test — all 529 tests pass
  • npm run build — clean build with no errors
  • npm run lint — no new lint warnings introduced

🤖 Generated with Claude Code

…output format docs

- Fix PowerShell WAV path quoting in playSound() to use double-quote escaping
  instead of single-quote escaping, which handles more special characters safely
- Add stopTeammate() exported helper for permanent teammate termination via JSON stdout
- Add JSDoc output format documentation to teammate-idle and task-completed hooks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 25, 2026 12:46
@maystudios maystudios merged commit 6b993ba into main Mar 25, 2026
5 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates MaxsimCLI hook utilities and hook script documentation to improve Windows sound playback reliability and to document/enable “stop teammate” control via JSON stdout.

Changes:

  • Adjust Windows PowerShell command construction in playSound() for WAV playback.
  • Add an exported stopTeammate(reason) helper that emits the JSON stop payload to stdout.
  • Add inline documentation to TeammateIdle/TaskCompleted hooks describing exit-code vs JSON-stdout control semantics.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
packages/cli/src/hooks/shared.ts Updates PowerShell WAV command quoting and adds stopTeammate() JSON-stop helper.
packages/cli/src/hooks/maxsim-teammate-idle.ts Adds hook output-format documentation (allow/block/stop).
packages/cli/src/hooks/maxsim-task-completed.ts Adds hook output-format documentation (allow/block/stop).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +151 to +152
process.stdout.write(`${payload}\n`);
process.exit(0);
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stopTeammate() writes to stdout and immediately calls process.exit(0). process.exit() can terminate the process before stdout is flushed when stdout is a pipe, which risks dropping the JSON control payload. To make the stop signal reliable, exit only after the write callback fires (or end stdout) instead of exiting synchronously right after write().

Suggested change
process.stdout.write(`${payload}\n`);
process.exit(0);
process.stdout.write(`${payload}\n`, () => {
process.exit(0);
});

Copilot uses AI. Check for mistakes.
Comment on lines +149 to +153
export function stopTeammate(reason: string): never {
const payload = JSON.stringify({ continue: false, stopReason: reason });
process.stdout.write(`${payload}\n`);
process.exit(0);
}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stopTeammate() introduces new hook-control behavior but isn’t covered by the existing hooks/shared.ts unit tests. Adding a small test that spies on process.stdout.write and process.exit would prevent regressions in the JSON payload format and exit semantics.

Copilot uses AI. Check for mistakes.
Comment on lines +106 to 116
// Use double-quoted string which handles spaces and most special chars
const escaped = soundFile.replace(/"/g, '\\"');
spawnSync(
'powershell',
[
'-NoProfile',
'-NonInteractive',
'-Command',
`$p='${soundFile.replace(/'/g, "''")}'; (New-Object System.Media.SoundPlayer $p).PlaySync()`,
`$p="${escaped}"; (New-Object System.Media.SoundPlayer $p).PlaySync()`,
],
{ stdio: 'ignore' },
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Windows-specific quoting/PowerShell command behavior in playSound() changed, but the existing hooks/shared.ts unit tests don’t assert the PowerShell argument string (and won’t exercise the win32 branch on non-Windows runners). Consider adding a unit test that mocks os.platform() to win32 and asserts the spawnSync('powershell', [...]) args so quoting regressions are caught.

Copilot uses AI. Check for mistakes.
Comment on lines +106 to 115
// Use double-quoted string which handles spaces and most special chars
const escaped = soundFile.replace(/"/g, '\\"');
spawnSync(
'powershell',
[
'-NoProfile',
'-NonInteractive',
'-Command',
`$p='${soundFile.replace(/'/g, "''")}'; (New-Object System.Media.SoundPlayer $p).PlaySync()`,
`$p="${escaped}"; (New-Object System.Media.SoundPlayer $p).PlaySync()`,
],
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PowerShell -Command string now uses a double-quoted literal ($p="..."). In PowerShell, double-quoted strings perform variable/subexpression expansion (e.g. $, $(), and backtick escapes), so valid Windows path characters like $ or ` can be misinterpreted and break playback (and it also makes the “handles special chars” comment inaccurate). Consider avoiding interpolation entirely by passing the path as a separate argument and reading it via $args[0] (or revert to a single-quoted literal with proper escaping).

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 5.13.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants